/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.gac.model;

import java.util.*;
import org.gac.messages.MessageCollection;

/**
 *
 * @author Tomek
 */
public abstract class CompositeStep extends Step
{

    protected LinkedList<Step> _innerSteps;

    public CompositeStep(String name)
    {
        super(name);
        _innerSteps = new LinkedList<Step>();
    }

    public CompositeStep()
    {
        this(null);
    }

    public Iterable<Step> InnerSteps()
    {
        return Collections.unmodifiableCollection(_innerSteps);
    }

    public boolean CanAddStep(Step child, int position)
    {
        Step s = this._parent;
        while (s != null)
        {
            if (s == child)
            {
                return false;
            }
            s = s._parent;
        }
        if (child == this)
        {
            return false;
        }
        return true;
    }

    public void AddStep(Step child, int position)
    {
        _innerSteps.add(position, child);
        child.setParent(this);
        child.setStepChangeListener(new IStepStateListener()
        {

            public void StepStateChanged(Step step)
            {
                if (_changeListener != null)
                {
                    _changeListener.StepStateChanged(CompositeStep.this);
                }
            }
        });

        if (_changeListener != null)
        {
            _changeListener.StepStateChanged(CompositeStep.this);
        }
    }

    public void AddStep(Step child)
    {
        AddStep(child, _innerSteps.size());
    }

    public void RemoveStep(Step child)
    {
        _innerSteps.remove(child);
        child.setParent(null);
        child.setStepChangeListener(null);
        if (_changeListener != null)
        {
            _changeListener.StepStateChanged(CompositeStep.this);
        }
    }

    @Override
    public final void Validate(MessageCollection messages)
    {
        for (Step s : _innerSteps)
        {
            s.Validate(messages);
        }
        ValidateImpl(messages);

    }

    public void moveChildTo(Step modelStep, int location)
    {
        int newLoc = location;
        int currentLoc = _innerSteps.indexOf(modelStep);
        if (newLoc > currentLoc)
        {
            newLoc--;
        }
        _innerSteps.remove(modelStep);
        _innerSteps.add(newLoc, modelStep);
        if (_changeListener != null)
        {
            _changeListener.StepStateChanged(CompositeStep.this);
        }
    }

    protected void ValidateImpl(MessageCollection messages)
    {
    }

    private boolean hasInDescendants(Step child)
    {
        for (Step s : _innerSteps)
        {
            if (s == child)
            {
                return true;
            }
            if (s instanceof CompositeStep)
            {
                if (((CompositeStep) s).hasInDescendants(child))
                {
                    return true;
                }
            }
        }
        return false;
    }
}
